import tester.*;

// Examples and tests for books, songs, images 
// and lists of books, songs, and images
@Example
class Examples{
	Examples(){}

	ISelector<Book> BookPred = new CheapBook();
	ISelector<Song> SongPred = new LongSong();
	ISelector<Image> ImagePred = new JPegImage();
	
	Book oms = new Book("Old Man and the Sea", "Hemingway", 30);
	Book eos = new Book("Elements of Style", "EBW", 20);
	Book htdp = new Book("HtDP", "MF", 60);
	Book ll = new Book("Little Lisper", "MF", 25);

	ILo<Book> mtlob = new MtLo<Book>();
	ILo<Book> blist2 = new ConsLo<Book>(this.oms, 
			new ConsLo<Book>(this.eos, this.mtlob));
	ILo<Book> blist3 = new ConsLo<Book>(this.htdp, this.blist2);

	Song help = new Song("Help", "Beatles", 283);
	Song hotelc = new Song("Hotel California", "Eagles", 276);
	Song yesterday = new Song("Yesterday", "Beatles", 195);

	ILo<Song> mtlos = new MtLo<Song>();
	ILo<Song> slist2 = new ConsLo<Song>(this.help, 
			new ConsLo<Song>(this.hotelc, this.mtlos));
	ILo<Song> slist3 = new ConsLo<Song>(this.yesterday, this.slist2);

	Image beach = new Image("Beach", "jpeg", 24348);
	Image park = new Image("Park", "gif", 33246);
	Image party = new Image("Party", "png", 4532);

	ILo<Image> mtloi = new MtLo<Image>();
	ILo<Image> ilist2 = new ConsLo<Image>(this.beach, 
			new ConsLo<Image>(this.park, this.mtloi));
	ILo<Image> ilist3 = new ConsLo<Image>(this.party, this.ilist2);

	@TestMethod
	// test the method size for all lists
	void testPick(Tester t){
		t.checkExpect(BookPred.pick(htdp), false);
		t.checkExpect(BookPred.pick(eos), false);
		t.checkExpect(BookPred.pick(oms), false);
		
		t.checkExpect(SongPred.pick(yesterday), true);
		t.checkExpect(SongPred.pick(hotelc), true);
		t.checkExpect(SongPred.pick(help), true);
		
		t.checkExpect(ImagePred.pick(beach), true);
		t.checkExpect(ImagePred.pick(park), false);
		t.checkExpect(ImagePred.pick(party), false);
	}
	
	@TestMethod
	// test the method size for all lists
	void testSame(Tester t){
		t.checkExpect(htdp.isSame(eos), false);
		t.checkExpect(eos.isSame(oms), false);
		t.checkExpect(oms.isSame(oms), true);
		
		t.checkExpect(yesterday.isSame(yesterday), true);
		t.checkExpect(hotelc.isSame(hotelc), true);
		t.checkExpect(help.isSame(hotelc), false);
		
		t.checkExpect(beach.isSame(park), false);
		t.checkExpect(park.isSame(park), true);
		t.checkExpect(party.isSame(beach), false);
	}
	
	@TestMethod
	// test the method size for all lists
	void testSize(Tester t){
		t.checkExpect(mtlob.size(), 0);
		t.checkExpect(blist2.size(), 2);
		t.checkExpect(blist3.size(), 3);

		t.checkExpect(mtlos.size(), 0);
		t.checkExpect(slist2.size(), 2);
		t.checkExpect(slist3.size(), 3);

		t.checkExpect(mtloi.size(), 0);
		t.checkExpect(ilist2.size(), 2);
		t.checkExpect(ilist3.size(), 3);
	}

	@TestMethod
	// test the method contains for all lists
	void testContains(Tester t){
		t.checkExpect(mtlob.size(), 0);
		t.checkExpect(blist2.size(), 2);
		t.checkExpect(blist3.size(), 3);

		t.checkExpect(mtlos.size(), 0);
		t.checkExpect(slist2.size(), 2);
		t.checkExpect(slist3.size(), 3);

		t.checkExpect(mtloi.size(), 0);
		t.checkExpect(ilist2.size(), 2);
		t.checkExpect(ilist3.size(), 3);
	}

	@TestMethod
	// test the method size for all lists
	void testValue(Tester t){
		t.checkExpect(mtlob.totalValue(), 0);
		t.checkExpect(blist2.totalValue(), 50);
		t.checkExpect(blist3.totalValue(), 110);

		t.checkExpect(mtlos.totalValue(), 0);
		t.checkExpect(slist2.totalValue(), 559);
		t.checkExpect(slist3.totalValue(), 754);

		t.checkExpect(mtloi.totalValue(), 0);
		t.checkExpect(ilist2.totalValue(), 57594);
		t.checkExpect(ilist3.totalValue(), 62126);
	}

	@TestMethod
	//test the method contains for all lists
	void testMakeString(Tester t){
		t.checkExpect(mtlob.makeString(), "");
		t.checkExpect(blist2.makeString(), 
				"Old Man and the Sea-Hemingway-30, Elements of Style-EBW-20, ");
		t.checkExpect(blist3.makeString(), 
				"HtDP-MF-60, Old Man and the Sea-Hemingway-30, Elements of Style-EBW-20, ");

		t.checkExpect(mtlos.makeString(), "");
		t.checkExpect(slist2.makeString(), 
				"Help-Beatles-283, Hotel California-Eagles-276, ");
		t.checkExpect(slist3.makeString(), 
				"Yesterday-Beatles-195, Help-Beatles-283, Hotel California-Eagles-276, ");

		t.checkExpect(mtloi.makeString(), "");
		t.checkExpect(ilist2.makeString(), 
				"Beach-jpeg-24348, Park-gif-33246, ");
		t.checkExpect(ilist3.makeString(), 
				"Party-png-4532, Beach-jpeg-24348, Park-gif-33246, ");
	}
	
	@TestMethod
	// test the method filter2 for all lists
	void testFilter(Tester t){
		t.checkExpect(mtlob.filter2(BookPred), mtlob);
		t.checkExpect(blist2.filter2(BookPred), mtlob);
		t.checkExpect(blist3.filter2(BookPred), mtlob);

		t.checkExpect(mtlos.filter2(SongPred), mtlos);
		t.checkExpect(slist2.filter2(SongPred), slist2);
		t.checkExpect(slist3.filter2(SongPred), slist3);

		t.checkExpect(mtloi.filter2(ImagePred), mtloi);
		t.checkExpect(ilist2.filter2(ImagePred), new ConsLo(beach, new MtLo()));
		t.checkExpect(ilist3.filter2(ImagePred), new ConsLo(beach, new MtLo()));
	}
}